using System;
using System.Drawing;
using System.Drawing.Text;
using System.Drawing.Drawing2D;
using System.ComponentModel;
using System.ComponentModel.Design;



namespace Camalon.Drawing.Shapes
{
	[ToolboxItem(true)]
    [Designer("Camalon.Drawing.Design.RectangleShapeDesigner, Camalon.Drawing.Design", typeof(IDesigner))]
    public class RectangleShape : Shape
	{
//		public RectangleShape(System.ComponentModel.IContainer container):this()
//		{
//			///
//			/// Required for Windows.Forms Class Composition Designer support
//			///
//			container.Add(this);
//
//		}

		public RectangleShape( ):base()
		{
		}

		protected override GraphicsPath MakePath(RectangleF bounds)
		{
			GraphicsPath path = new GraphicsPath();
			path.StartFigure();


			//TOP Left
			//------------------------------------------------------------------------------------------------
			if( _topLeft.Width > 0f && _topLeft.Height > 0f)
			{
				PointF pt = Convert( _topLeft, bounds.Size );
				if( _topLeft.Style == CornerStyle.Elliptic)
					path.AddArc( bounds.Left, bounds.Top, 2*pt.X, 2*pt.Y, -90f, -90f);
				else
				{
					PointF p1 = new PointF( bounds.Left+ pt.X, bounds.Top);
					PointF p2 = new PointF( bounds.Left, bounds.Top + pt.Y );
					path.AddLine( p1, p2);		
					//				path.AddLine(  new PointF( bounds.Left, bounds.Bottom), new PointF( bounds.Right, bounds.Bottom));
					//				path.AddLine(  new PointF( bounds.Right, bounds.Bottom), new PointF( bounds.Right, bounds.Top));
				}
			}
			else 
				path.AddLine( bounds.Location, bounds.Location);
			

			//Bottom left
			if( _bottomLeft.Width > 0f && _bottomLeft.Height > 0f)
			{
				PointF pt = Convert( _bottomLeft, bounds.Size );
				if( _bottomLeft.Style == CornerStyle.Elliptic)
					path.AddArc( bounds.Left, bounds.Bottom - 2*pt.Y, 2*pt.X, 2*pt.Y, -180f, -90f);
				else
				{
					PointF p1 = new PointF( bounds.Left + pt.X, bounds.Bottom);
					PointF p2 = new PointF( bounds.Left, bounds.Bottom - pt.Y );
					path.AddLine( p2, p1);		
				}
			}
			else 
			{	
				PointF p1 = new PointF( bounds.Left, bounds.Bottom);
				path.AddLine( p1, p1);
			}

			//Bottom right
			if( _bottomRight.Width > 0f && _bottomRight.Height > 0f)
			{
				PointF pt = Convert( _bottomRight, bounds.Size );
				if( _bottomRight.Style == CornerStyle.Elliptic)
					path.AddArc( bounds.Right - 2*pt.X, bounds.Bottom - 2*pt.Y, 2*pt.X, 2*pt.Y, -270f, -90f);
				else
				{
					PointF p1 = new PointF( bounds.Right - pt.X, bounds.Bottom);
					PointF p2 = new PointF( bounds.Right, bounds.Bottom - pt.Y );
					path.AddLine( p1, p2);		
				}
			}
			else 
			{	
				PointF p1 = new PointF( bounds.Right, bounds.Bottom);
				path.AddLine( p1, p1);
			}


			//topright
			if( _topRight.Width > 0f && _topRight.Height > 0f)
			{
				PointF pt = Convert( _topRight, bounds.Size );
				if( _topRight.Style == CornerStyle.Elliptic)
					path.AddArc( bounds.Right - 2*pt.X, bounds.Top, 2*pt.X, 2*pt.Y, 0f, -90f);
				else
				{
					PointF p1 = new PointF( bounds.Right, bounds.Top + pt.Y );
					PointF p2 = new PointF( bounds.Right - pt.X, bounds.Top);
					path.AddLine( p1, p2);		
				}
			}
			else 
			{	
				PointF p1 = new PointF( bounds.Right, bounds.Top);
				path.AddLine( p1, p1);
			}

			path.CloseFigure();
			return path;
		}


		private Corner ValidateCorner(Corner value)
		{
			if( value.Width > 1f) value.Width = 1f;
			if( value.Width < 0f) value.Width = 0f;
			if( value.Height > 1f) value.Height = 1f;
			if( value.Height < 0f) value.Height = 0f;

			return value;
		}

		private PointF Convert( Corner value , SizeF size)
		{

			float w = value.Width * size.Width;
			float h = value.Height * size.Height;
			return new PointF( w, h );
		}

		private Corner Convert( PointF sizeValue , SizeF size, CornerStyle style)
		{

			float w = sizeValue.X / size.Width;
			float h = sizeValue.Y / size.Height;

			return new Corner( w, h, style);
		}


		private Corner _topLeft = Corner.Empty;
		[Category("Corners")]
		[DefaultValue( typeof( Corner), "Empty")]
		public Corner TopLeft
		{
			get{ return _topLeft;}
			set
			{
				value = ValidateCorner( value);
				if( _topLeft == value) return;
				_topLeft = value;
				ResetPath();
			}
		}

		private Corner _topRight = Corner.Empty;
		[DefaultValue( typeof( Corner), "Empty")]
		[Category("Corners")]
		public Corner TopRight
		{
			get{ return _topRight;}
			set
			{
				value = ValidateCorner( value);
				if( _topRight == value) return;
				_topRight = value;

				ResetPath();
			}
		}

		private Corner _bottomLeft = Corner.Empty;
		[DefaultValue( typeof( Corner), "Empty")]
		[Category("Corners")]
		public Corner BottomLeft
		{
			get{ return _bottomLeft;}
			set
			{
				value = ValidateCorner( value);
				if( _bottomLeft == value) return;
				_bottomLeft = value;

				ResetPath();
			}
		}

		private Corner _bottomRight = Corner.Empty;
		[DefaultValue( typeof( Corner), "Empty")]
		[Category("Corners")]
		public Corner BottomRight
		{
			get{ return _bottomRight;}
			set
			{
				value = ValidateCorner( value);
				if( _bottomRight == value) return;
				_bottomRight = value;

				ResetPath();
			}
		}



		[Browsable( false)]
		[DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden)]
		public override PointF[] ControlPoints
		{
			get
			{
				RectangleF b = base.GetBasePathBounds();
				SizeF size = b.Size;

				//TopLeft
				PointF tl = Convert(_topLeft, size);
				tl.X += b.Left;
				tl.Y += b.Top;

				//TopRight
				PointF tr = Convert(_topRight, size);
				tr.X = b.Right - tr.X;
				tr.Y += b.Top;

				//BottomRight
				PointF br = Convert(_bottomRight, size);
				br.X = b.Right - br.X;
				br.Y = b.Bottom - br.Y;

				//BottomLeft
				PointF bl = Convert(_bottomLeft, size);
				bl.X += b.Left;
				bl.Y  = b.Bottom - bl.Y;

				return new PointF[]{ tl, tr, br, bl};
			}
			set
			{
				if( value == null  || value.Length  == 0) return;

				RectangleF b = base.GetBasePathBounds();
				SizeF size = b.Size;

				//TopLeft
				PointF tl = value[0];
				tl.X -= b.Left; 
				tl.Y -= b.Top; 
				_topLeft = ValidateCorner(Convert( tl, size, _topLeft.Style));

				//TopRight
				PointF tr = value[1];
				tr.X = b.Right - tr.X; 
				tr.Y -= b.Top; 
				_topRight = ValidateCorner(Convert( tr, size, _topRight.Style));
				
				//BottomRight
				PointF br = value[2];
				br.X = b.Right -  br.X; 
				br.Y = b.Bottom - br.Y; 
				_bottomRight = ValidateCorner(Convert( br, size, _bottomRight.Style));

				//BottomLeft
				PointF bl = value[3];
				bl.X -= b.Left; 
				bl.Y  = b.Bottom - bl.Y; 
				_bottomLeft = ValidateCorner(Convert( bl, size, _bottomLeft.Style));

				ResetPath(); 

			}
		}


	}
}
